/**
 *    5
 *  1 2 4 3
 *    0
 */

var bottom_left_to_front = {
  0: {
    1: 2,
    2: 4,
    3: 1,
    4: 3,
  },
  5: {
    1: 3,
    2: 1,
    3: 4,
    4: 2,
  },
  1: {
    0: 3,
    3: 5,
    5: 2,
    2: 0,
  },
  4: {
    0: 2,
    2: 5,
    5: 3,
    3: 0,
  },
  2: {
    0: 1,
    1: 5,
    5: 4,
    4: 0,
  },
  3: {
    0: 4,
    4: 5,
    5: 1,
    1: 0,
  },

}

var colorMap = {
  0: XColor.Red,
  1: XColor.Orange,
  2: XColor.Blue,
  3: XColor.Green,
  4: XColor.Pink,
  5: XColor.Yellow,

}

/**色块迷踪游戏逻辑 */
class ColorCubeGame {
  constructor(cells: number[][]) {
    this.cells = cells;
    let a = new Array(10);
    for (let i = 0; i < 10; i++) {
      a[i] = Array(10);
      for (let j = 0; j < 10; j++) {
        a[i][j] = this.neighborNum(i, j);
      }
    }
    console.table(cells);
    console.table(a);
  }
  getStartCell(): any[] {
    for (let row = this.cells.length - 1; row >= 0; row--) {
      for (let col = 0; col < this.cells[row].length; col++) {
        if (this.neighborNum(row, col) == 1)
          return [row, col, 0, 1];
      }
    }
    return [];
  }
  fromMat2List(): any[] {
    let head: any[] = (function () {
      for (let row = this.cells.length - 1; row >= 0; row--) {
        for (let col = 0; col < this.cells[row].length; col++) {
          if (this.neighborNum(row, col) == 1)
            return [row, col, 0, 1];
        }
      }
      return [];
    }).call(this);

    if (head.length === 0)
      return [];

    let list = [head];
    let cur = head, last = [-1, -1, 0, 1];
    while (true) {
      let row = cur[0] as number;
      let col = cur[1] as number;

      let [bottom, left] = cur.slice(2, 4)
      let front = bottom_left_to_front[bottom][left];
      if (col > 0 && this.cells[row][col - 1] != 0 && last.slice(0, 2).toString() != [row, col - 1].toString()) {
        let status = [left, 5 - bottom];
        list.push([row, col - 1].concat(status));

      } else if (row > 0 && this.cells[row - 1][col] != 0 && last.slice(0, 2).toString() != [ row - 1,col].toString()) {
        let status = [5 - front, left];
        list.push([row-1, col].concat(status));

      } else if (col < (this.cells.length - 1) && this.cells[row][col + 1] != 0 && last.slice(0, 2).toString() != [row, col + 1].toString()) {
        let status = [5 - left, bottom];
        list.push([row, col + 1].concat(status));

      } else if (row < (this.cells.length - 1) && this.cells[row + 1][col] != 0 && last.slice(0, 2).toString() != [row+1, col].toString()) {
        let status = [front, left];
        list.push([row + 1, col].concat(status));

      } else {
        return list;
      }
      last = cur;
      cur = list[list.length-1];

    }
  }

  neighborNum(row: number, col: number): number {
    if (this.cells[row][col] === 0)
      return 0;
    let cnt = 0;
    if (col > 0 && this.cells[row][col - 1] != 0)
      cnt += 1;
    if (row > 0 && this.cells[row - 1][col] != 0)
      cnt += 1;
    if (col < (this.cells.length - 1) && this.cells[row][col + 1] != 0)
      cnt += 1;
    if (row < (this.cells.length - 1) && this.cells[row + 1][col] != 0)
      cnt += 1;
    return cnt;
  }

  isCellVisible(row: number, col: number): boolean {
    return this.cells[row][col] != 0;
  }

  private cells: number[][];
};